/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package spreadsheet.helpers;

import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JTable;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;
import utils.dispatchers.KeyBoardDispatcher;

/**
 *
 * @author Nobody
 */
public class ColumnHeaderListener extends MouseAdapter implements Observer {

    private boolean isControlPressed;
    private boolean isShiftPressed;
    private int lastSelectedColumnWithoutModifier = -1;

    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof KeyBoardDispatcher) {
            KeyBoardDispatcher key = (KeyBoardDispatcher) o;
            isControlPressed = key.isControlDown();
            isShiftPressed = key.isShiftDown();
        }
    }

    public ColumnHeaderListener() {
        KeyBoardDispatcher.getInstance().addObserver(this);
    }

    @Override
    public void mouseClicked(MouseEvent evt) {
        JTable table = ((JTableHeader) evt.getSource()).getTable();
        TableColumnModel colModel = table.getColumnModel();

        // The index of the column whose header was clicked
        int vColIndex = colModel.getColumnIndexAtX(evt.getX());
        int mColIndex = table.convertColumnIndexToModel(vColIndex);

        // Return if not clicked on any column header
        if (vColIndex == -1) {
            return;
        }

        // Determine if mouse was clicked between column heads
        Rectangle headerRect = table.getTableHeader().getHeaderRect(vColIndex);
        if (vColIndex == 0) {
            headerRect.width -= 3;    // Hard-coded constant
        } else {
            headerRect.grow(-3, 0);   // Hard-coded constant
        }
        if (!headerRect.contains(evt.getX(), evt.getY())) {
            // Mouse was clicked between column heads
            // vColIndex is the column head closest to the click

            // vLeftColIndex is the column head to the left of the click
            int vLeftColIndex = vColIndex;
            if (evt.getX() < headerRect.x) {
                vLeftColIndex--;
            }
        }

        if (isShiftPressed) {
            table.addColumnSelectionInterval(mColIndex, mColIndex);
            table.addColumnSelectionInterval(lastSelectedColumnWithoutModifier, mColIndex);
            table.addRowSelectionInterval(0, table.getRowCount() - 1);
        } else if (isControlPressed) {
            if (Arrays.asList(table.getSelectedColumns()).isEmpty()) {
                table.setColumnSelectionInterval(mColIndex, mColIndex);
                table.setRowSelectionInterval(0, table.getRowCount() - 1);
            } else {
                table.addColumnSelectionInterval(mColIndex, mColIndex);
                table.addRowSelectionInterval(0, table.getRowCount() - 1);
            }

        } else {
            if (Arrays.asList(table.getSelectedColumns()).contains(mColIndex)) {
                table.removeColumnSelectionInterval(mColIndex, mColIndex);
                table.removeRowSelectionInterval(0, table.getRowCount() - 1);

            } else {
                table.setColumnSelectionInterval(mColIndex, mColIndex);
                table.setRowSelectionInterval(0, table.getRowCount() - 1);
            }
            lastSelectedColumnWithoutModifier = mColIndex;
        }
    }
}
